﻿using System;
using System.Runtime.InteropServices;
using System.Text;

namespace BBB.Valuta.Savers
{
    public class PrintSaver : Saver
    {
        private struct DocInfo
        {
            public string PDocName;
            public string POutputFile;
            public string PDatatype;
        } ;

        private IntPtr _printer;
        private DocInfo _docInfo;

        public string PrinterName { get; set; }

        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, IntPtr pDefault);
        [DllImport("winspool.drv", SetLastError = true)]
        private static extern int StartDocPrinter(IntPtr hPrinter, UInt32 level, ref DocInfo pDocInfo);
        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool StartPagePrinter(IntPtr hPrinter);
        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool WritePrinter(IntPtr hPrinter, byte[] pBuf, UInt32 cbBuf, out UInt32 pcWritten);
        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool EndPagePrinter(IntPtr hPrinter);
        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool EndDocPrinter(IntPtr hPrinter);
        [DllImport("winspool.drv", SetLastError = true)]
        private static extern bool ClosePrinter(IntPtr hPrinter);

        public PrintSaver(string printrName)
        {
            PrinterName = printrName;
        }
        
        public override void Execute()
        {
            if (!OpenPrinter(PrinterName, out _printer, new IntPtr()))
            {
                Int32 errorCode = Marshal.GetLastWin32Error();
                if (errorCode == 1801)
                    throw new Exception("Незнайдено принтер");
                throw new Exception(errorCode.ToString());
            }
            Encoding ascii = Encoding.GetEncoding(866);
            Encoding utf8 = Encoding.UTF8;

            //// Convert the string into a byte[].
            byte[] unicodeBytes = utf8.GetBytes(Body);

            //// Perform the conversion from one encoding to the other.
            byte[] asciiBytes = Encoding.Convert(utf8, ascii, unicodeBytes);

            ////// Convert the new byte[] into a char[] and then into a string.
            ////// This is a slightly different approach to converting to illustrate
            ////// the use of GetCharCount/GetChars.
            //char[] asciiChars = new char[ascii.GetCharCount(asciiBytes, 0, asciiBytes.Length)];
            //ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0);
            //string asciiString = new string(asciiChars);
            //sw.Write(asciiString);


            _docInfo = new DocInfo {PDocName = "Receipts", PDatatype = "RAW"};
            StartDocPrinter(_printer, 1, ref _docInfo);
            StartPagePrinter(_printer);
            UInt32 r;
            WritePrinter(_printer, asciiBytes, (UInt32)asciiBytes.Length, out r);
            EndPagePrinter(_printer);
            EndDocPrinter(_printer);
            ClosePrinter(_printer);
        }
    }
}
